package com.shi.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.shi.annotation.Auth;
import com.shi.annotation.MyLog;
import com.shi.common.Result;
import com.shi.entity.dto.AccountAddDto;
import com.shi.entity.dto.AccountBindEmailDto;
import com.shi.entity.dto.AccountForgetPasswordDto;
import com.shi.entity.dto.AccountUpdateSelfPasswordDto;
import com.shi.entity.po.Account;
import com.shi.entity.vo.AccountVO;
import com.shi.entity.vo.SessionAccountVO;
import com.shi.enums.AuthCodeEnum;
import com.shi.enums.LogType;
import com.shi.service.AccountService;
import com.shi.util.PasswordUtil;
import com.shi.util.UserContext;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.List;

/**
 * (Account)表控制层
 *
 * @author makejava
 * @since 2024-05-16 17:18:00
 */
@Api(tags = "用户管理")
@RestController
@RequestMapping("/account")
public class AccountController {
    /**
     * 服务对象
     */
    @Resource
    private AccountService accountService;

    @ApiOperation("获取用户信息")
    @GetMapping("/info")
    @Auth
    public Result getUserInfo() {
        Integer userId = UserContext.userId();
        SessionAccountVO sessionAccountVO = UserContext.get();
        Account account = accountService.getById(userId);
        BeanUtils.copyProperties(account,sessionAccountVO);
        return Result.ok(sessionAccountVO);
    }

    /**
     * 通过主键查询单条数据
     *
     * @return 单条数据
     */
    @ApiOperation("查询全部用户")
    @Auth(hasPerm = AuthCodeEnum.PERM_ACCOUNT_SELECT)
    @GetMapping("/all")
    public Result queryAll() {
        List<Account> accountList = accountService.list(new LambdaQueryWrapper<Account>().orderByDesc(Account::getCreateTime));
        List<AccountVO> accountVOList = Account.toAccountVOList(accountList);
        return Result.ok(accountVOList);
    }

    @ApiOperation("条件模糊查询")
    @GetMapping("/like")
    @Auth(hasPerm = {AuthCodeEnum.PERM_ROLE_SELECT,AuthCodeEnum.PERM_ACCOUNT_GIVE_ROLES})
    public Result listByCondition(@RequestParam("like") String likeProp){
        List<AccountVO> list=accountService.listByCondition(likeProp);
        return Result.ok(list);
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @ApiOperation("通过id查询用户")
    @Auth(hasPerm = AuthCodeEnum.PERM_ACCOUNT_SELECT)
    @GetMapping("/{id}")
    public Result queryById(@PathVariable("id") Integer id) {
        Account account = accountService.getById(id);
        return Result.ok(account);
    }

    /**
     * 新增数据
     *
     * @param addDto 实体
     * @return 新增结果
     */
    @ApiOperation("添加用户")
    @PostMapping
    @MyLog(type = LogType.INSERT)
    @Auth(hasPerm = AuthCodeEnum.PERM_ACCOUNT_INSERT_DELETE_UPDATE)
    public Result add(@RequestBody AccountAddDto addDto) {
        accountService.add(addDto);
        return Result.ok();
    }

    @ApiOperation("为用户分配角色")
    @PostMapping("/giveRoles/{accountId}")
    @Auth(hasPerm = AuthCodeEnum.PERM_ACCOUNT_GIVE_ROLES)
    @MyLog(type = LogType.OTHER)
    public Result giveRoles(@RequestBody List<Integer> roleIds, @PathVariable("accountId") Integer accountId) {
        accountService.giveRoles(roleIds, accountId);
        return Result.ok();
    }

    /**
     * 编辑数据
     *
     * @param account 实体
     * @return 编辑结果
     */
    @ApiOperation("重置用户密码")
    @PutMapping("/resetPassword")
    @Auth(hasPerm = AuthCodeEnum.PERM_ACCOUNT_INSERT_DELETE_UPDATE)
    @MyLog(type = LogType.UPDATE)
    public Result resetPassword(@RequestBody Account account) {
        account.setPassword(PasswordUtil.encode(account.getPassword()));
        accountService.updateById(account);
        return Result.ok();
    }

    /**
     * 删除数据
     *
     * @param id 主键
     * @return 删除是否成功
     */
    @ApiOperation("通过id删除用户")
    @DeleteMapping("/{id}")
    @Auth(hasPerm = AuthCodeEnum.PERM_ACCOUNT_INSERT_DELETE_UPDATE)
    @MyLog(type = LogType.DELETE)
    public Result removeById(@PathVariable("id") Integer id) {
        accountService.removeById(id);
        return Result.ok();
    }

    /**
     * 批量删除数据
     *
     * @param ids 主键列表
     * @return 删除是否成功
     */
    @ApiOperation("通过ids批量删除用户")
    @DeleteMapping("/batch")
    @Auth(hasPerm = AuthCodeEnum.PERM_ACCOUNT_INSERT_DELETE_UPDATE)
    @MyLog(type = LogType.DELETE)
    public Result removeBatchByIds(@RequestBody List<Integer> ids) {
        this.accountService.removeBatchByIds(ids);
        return Result.ok();
    }

    @ApiOperation("通过用户id查询拥有的角色id")
    @GetMapping("/roles/{accountId}")
    @Auth(hasPerm = AuthCodeEnum.PERM_ACCOUNT_GIVE_ROLES)
    public Result queryRoleIdsByAccountId(@PathVariable("accountId") Integer accountId) {
        List<Integer> roleIds = accountService.queryRoleIdsByAccountId(accountId);
        return Result.ok(roleIds);
    }

    /**
     * 处理用户忘记密码操作
     *
     * @param forgetPasswordDto
     * @return
     */
    @ApiOperation("忘记密码")
    @PostMapping("/forgetPassword")
    @MyLog(type = LogType.OTHER)
    public Result forgetPassword(@Valid @RequestBody AccountForgetPasswordDto forgetPasswordDto, HttpSession session) {
        accountService.forgetPassword(forgetPasswordDto,session);
        return Result.ok();
    }

    /**
     * 修改自己的密码
     * @return
     */
    @ApiOperation("修改个人账号的密码")
    @PostMapping("/updateSelf/password")
    @Auth
    @MyLog(type = LogType.UPDATE)
    public Result updateSelfPassword(@Valid @RequestBody AccountUpdateSelfPasswordDto updateSelfPasswordDto){
        accountService.updateSelfPassword(updateSelfPasswordDto);
        return Result.ok();
    }

    @ApiOperation("修改个人账号绑定的邮箱")
    @Auth
    @PostMapping("/bindEmail")
    @MyLog(type = LogType.UPDATE)
    public Result updateBindEmail(@Valid @RequestBody AccountBindEmailDto accountBindEmailDto,HttpSession session){
        accountService.updateBindEmail(accountBindEmailDto,session);
        return Result.ok();
    }

    @ApiOperation("更新个人用户信息")
    @PutMapping
    @Auth
    @MyLog(type = LogType.UPDATE)
    public Result update(@RequestBody Account account){
        accountService.updateById(account);
        return Result.ok();
    }
}

